<template>
  <div>
    <div id="main"></div>
    <div class="btns">
      <div class="btn" v-for="(d, i) in testData" :key="i" @click="chooseIndex = i">{{d.join(',')}}</div>
    </div>
  </div>
</template>

<script>
// 测试数据
let testData = [
  [100,280,50,150,180],
  [50,120,150,50,100],
  [50,150,300],
  [320],
  [68,222,333,444],
]
import * as zrender from "zrender";
export default {
  data() {
    return {
      config: {
        barGap: 60,
        barWidth: 50,
        delay: 200,
      },
      testData,
      chooseIndex: 0,
      chartData: [],
      bars: [],
    };
  },
  watch:{
    // 数据改变，更新绘图
    chooseIndex: function(){
      console.log('数据改变，更新绘图');
      this.updateData();
    }
  },
  mounted() {
    this.zr = zrender.init(document.getElementById("main"));
    this.barGroup = new zrender.Group();
    this.barGroup.name = "bars";
    this.LinearGradient = new zrender.LinearGradient(0, 1, 1, 1, [
      { offset: 0, color: "#06B5D7" },
      { offset: 0.5, color: "#44C0C1" },
      { offset: 1, color: "#71C8B1" },
    ])
    this.zr.add(this.barGroup);
    // 初始化数据
    this.updateData();
  },
  methods: {
    // 初始化数据
    updateData() {
      this.chartData = [...this.testData[this.chooseIndex]]
      this.chartData.forEach((d, i) => {
        if (!this.bars[i]) {
          // A、新增柱子
          this.bars[i] = {
            _data: d,
            x: 0,
            y:
              i * (this.config.barWidth + this.config.barGap) +
              this.config.barGap,
          };
          this.bars[i].el = this.addBar(this.bars[i]);
        }else{
           // B、修改柱子
           this.bars[i]._data = d;
           this.bars[i].el._data = d;
           this.updateBar(this.bars[i].el);
        }
      });
      for(let i = this.bars.length; i > this.chartData.length; i--){
        // C、删除柱子
        this.deleteBar(this.bars[i-1].el)
        this.bars.pop();
      }
    },
    // 新增的柱子
    addBar(bar) {
      let el = new zrender.Rect({
        shape: {
          x: bar.x,
          y: bar.y,
          width: 0,
          height: this.config.barWidth,
          r: [0, 8, 8, 0],
        },
        style: {
          fill: this.LinearGradient,
        },
        textContent: new zrender.Text({
          x: bar.x + bar._data,
          y: bar.y + this.config.barWidth / 2,
          style:{
            text: bar._data,
            fill: '#000',
            align: 'left',
            verticalAlign: 'center',
          }
        })
      });
      this.barGroup.add(el);
      el._data = bar._data;
      this.showBar(el);
      return el;
    },
    // 柱子从无到有
    showBar(el) {
      el.animate("shape", false)
        .when(1000, { width: el._data })
        .during(function(rect, process){
          
          el.getTextContent().attr('x', rect.x + rect.width + 10)
          el.getTextContent().attr('style', {
            text: (el._data * process).toFixed(0),
          })
        })
        .start("elasticOut");
    },
    // 改变柱子
    updateBar(el) {
      el.animate("shape", false)
        .when(400, { width: el._data })
        .start("quarticOut");
    },
    // 删除柱子
    deleteBar(el) {
      el.animate('style')
        .when(300, {opacity: 0})
        .start()
      el.animate('shape')
        .when(300, {width: 0})
        .start()
        .done(()=>{
          this.barGroup.remove(el)
        })
    },
  },
};
</script>

<style scoped>
#main {
  width: 80vw;
  height: 90vh;
  border: 1px solid #ccc;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.btns{
  position: fixed;
  right: 0;
  top: 0;
}
.btn{
  font-size: 12px;
  cursor: pointer;
  background-color: #3498db;
  color: #fff;
  width: 120px;
  text-align: center;
  margin: 10px;
  padding: 4px 0;
  border-radius: 10px;
}
</style>
